/*
Plugin sprawia ze zbanowany komenda amx_nickban gracz nie zadaje obrazen
CVAR:
amx_nickban_active (domyslnie 1)
	0 - Wylacza plugin
	1 - Wlacza plugin

amx_nickban_with_cban (domyslnie 0)
	0 - Brak integracji z "Zabijaka Config Ban"
	1 - Integracja z "Zabijaka Config Ban" przy komendzie amx_cban zaklada tez amx_nickban
	
amx_nickban_log (domyslnie 1)
	0 - Nie zapisuje logow o banie/unbanie
	1 - Zapisuje logi
	
amx_nickban_skip_steam (domyslnie 1)
	0 - Banuje wszystkich graczy
	1 - Nie banuje graczy ze Steamem
	
amx_nickban_lock_name (domyslnie 0)
	0 - Pozwala na zmiane nickow
	1 - Nie pozwala na zmiane nickow

amx_nickban_remember_name (domyslnie 1)
	0 - Nicki nie sa pamietane, po kazdej zmianie sprawdzany jest status bana
	1 - Nick i status bana sa pamietane po zalogowaniu gracza

amx_nickban_with_amxbans (domyslnie 0)
	0 - Brak integracji z amx_bans (forward amxbans_player_flagged)
	1 - Integracja z amxbans przy komendzie amx_ban zaklada tez amx_nickban
	
	
Komendy:
	amx_nickban [nick lub #authid] - banuje gracza
	amx_addzban [nick] - Dodaje nick do zbanowanych
	amx_delzban [nick] - zdejmuje nick ze zbanowanych (jesli gracz o danym nicku jest podlaczony jest odbanowywany)
	amx_nickunban [nick lub #authid] - odbanowuje gracza
	amx_nickbanmenu - menu do banowania graczy
	amx_nickunbanmenu  - menu do odbanowywania
*/

#include <amxmodx>
#include <amxmisc>
#include <nvault>
#include <hamsandwich>

#define PLUGIN "Zabijaka No Damage Ban"
#define VERSION "1.0"
#define AUTHOR "Zabijaka"
#define MAX_NAME_LEN 33
#define MAX_PLAYERS 33
#define TASK_CHECK_FOR_BAN 33


new gMaxPlayers;
new gForwardHandle;
new gNvaultHandle;
new gCvarWithCban;
new gCvarLog;
new gCvarSkipSteam;
new gCvarActive;
new gCvarLockName;
new gCvarRememberName;
new gCvarWithAmxbans;

new gPlayerBanned[MAX_PLAYERS];
new gPlayerNames[MAX_PLAYERS][MAX_NAME_LEN];
new const gInfoBan[] = "[ZBAN] Gracz %s zbanowany";
new const gInfoUnban[] = "[ZBAN] Gracz %s odbanowany";
new const gamx_nickBAN_LOG[] = "amx_nickban.log";
new const gInfoBanned[] = "%s [%s] zbanowal %s";
new const gInfoUnbanned[] = "%s [%s] odbanowal %s";
new const gPlayerWithSteam[] = "Gracz %s ma steam";
new const gNickNotBanned[] = "Nick %s nie jest zbanowany";
new const gName[ ] = "name";
new const gNick[ ] = "nick";
new const gNickAuthId[ ] = "nick lub #authid";
new const g1[] = "1";
new const g0[] = "0";
new const gNoPlayers[] = "Brak Graczy";



new resut;

public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
	gMaxPlayers = get_maxplayers();
	register_clcmd("amx_nickban", "nickBan", ADMIN_BAN, gNickAuthId);
	register_clcmd("amx_addnickban", "addNickBan", ADMIN_BAN, gNick);
	register_clcmd("amx_delnickban", "delNickBan", ADMIN_BAN, gNick);
	register_clcmd("amx_nickunban", "nickUnban", ADMIN_BAN, gNick);
	register_clcmd("amx_nickbanmenu", "nickBanMenu", ADMIN_BAN);
	register_clcmd("amx_nickunbanmenu", "nickUnbanMenu", ADMIN_BAN);
		
	gCvarWithCban = register_cvar("amx_nickban_with_cban", g0);
	gCvarLog = register_cvar("amx_nickban_log", g1);
	gCvarSkipSteam = register_cvar("amx_nickban_skip_steam", g1);
	gCvarActive = register_cvar("amx_nickban_active", g1);
	gCvarLockName = register_cvar("amx_nickban_lock_name", g0);
	gCvarRememberName = register_cvar("amx_nickban_remember_name", g1);
	gCvarWithAmxbans = register_cvar("amx_nickban_with_amxbans", g0);
	gNvaultHandle = nvault_open("amx_nickban");
	RegisterHam(Ham_TakeDamage, "player", "TakeDamage");
	gForwardHandle = CreateMultiForward("amx_nickban_player_banned", ET_CONTINUE, FP_CELL, FP_CELL);
	
}

public client_infochanged( id ){	
	static szNewName[ MAX_NAME_LEN ], szOldName[ MAX_NAME_LEN ];
	get_user_info( id, gName, szNewName, MAX_NAME_LEN -1 );
	
	if(get_pcvar_num(gCvarLockName)){

		get_user_name( id, szOldName,MAX_NAME_LEN -1 );	
		if( !equal( szNewName, szOldName ) ) {
			set_user_info( id, gName, szOldName );
		}
	} else {
		strtoupper(szNewName);
		new timeStamp;		
		new vData[MAX_NAME_LEN];
		
		if(nvault_lookup(gNvaultHandle, szNewName, vData, charsmax(vData),timeStamp))
			gPlayerBanned[id] = 1;
		else
			gPlayerBanned[id] =  0;
	}
}

public TakeDamage(id, idinflictor, idattacker, Float:damage, damagebits){
	if(!get_pcvar_num(gCvarActive))
		return HAM_IGNORED;
	if( (0 < idattacker < gMaxPlayers ) && (0 < id < gMaxPlayers)){
		if(gPlayerBanned[idattacker] && id != idattacker){			
			SetHamParamFloat(4, 0.0);
		}
	}
	return HAM_IGNORED;	
}



public nickBan(id, level, cid){
	if(!get_pcvar_num(gCvarActive))
		return PLUGIN_HANDLED;
	if(!cmd_access(id,level,cid,2)) 
		return PLUGIN_HANDLED;
	new argGracz[MAX_NAME_LEN];
	
	read_argv(1, argGracz, MAX_NAME_LEN -1);
	
	new player = cmd_target(id, argGracz, CMDTARGET_ALLOW_SELF);
	if(player && player < MAX_PLAYERS) {
		banPlayerById(id,player, 1);
	}
	return PLUGIN_HANDLED;
}

public nickBanMenu(id, level, cid) {
	if(!get_pcvar_num(gCvarActive))
		return PLUGIN_HANDLED;
	if(!cmd_access(id,level,cid,1)) 
		return PLUGIN_HANDLED;
	new menu = menu_create("\rZabijaka Nick Ban Menu:", "menu_handler");
	new players[32];
	new num;
	get_players(players, num);
	new sName[MAX_NAME_LEN *2 + 6];
	new tempid;
	new sTempid[3];
	new iNum = 0;
	new skipSteam = get_pcvar_num(gCvarSkipSteam);
	new name[MAX_NAME_LEN];
	new lockName =get_pcvar_num(gCvarLockName);
	for(new i=0;i< num;i ++){
		tempid = players[i];
		if(skipSteam){
			get_user_authid(tempid, sName, charsmax(sName));
			if(isValidSteam(sName))
			    continue;
		}
		sName[0] = 0;
		get_user_name(tempid, sName, charsmax(sName));
		
		num_to_str(tempid, sTempid, 2);
		if(!lockName){			
			copy(name, MAX_NAME_LEN -1, gPlayerNames[tempid]);
			if(!equali(sName, name))
			format(sName, charsmax(sName), "%s [%s]", sName, name);
		}
		menu_additem(menu, sName, sTempid, 0);
		iNum++;
	}
	if(iNum)
		menu_display(id, menu, 0);
	else{
		client_print(id, print_chat, gNoPlayers);
		menu_destroy(menu);
	}
	return PLUGIN_HANDLED;
}

public menu_handler(id, menu, item)
{
	if( item == MENU_EXIT )
	{
		menu_destroy(menu);
		return PLUGIN_HANDLED;
	}

	new data[6], szName[64];
	new acc, callback;
	menu_item_getinfo(menu, item, acc, data, charsmax(data), szName, charsmax(szName), callback);
	new tempid = str_to_num(data);	
	banPlayerById(id, tempid ,1);	
	menu_destroy(menu);
	return PLUGIN_HANDLED;
}
public addNickBan(id, level, cid){
	if(!get_pcvar_num(gCvarActive))
		return PLUGIN_HANDLED;
	if(!cmd_access(id,level,cid,2)) 
		return PLUGIN_HANDLED;
	new argGracz[MAX_NAME_LEN];
	
	read_argv(1, argGracz, MAX_NAME_LEN - 1);
	
	new player = -1;
	new players[32];
	new num;
	get_players(players, num);
	new tempId;
	new name[MAX_NAME_LEN];
	new remName = get_pcvar_num(gCvarRememberName);
	for(new i=0;i<num;i++){
		tempId = players[i];
		if(remName){
			copy(name, MAX_NAME_LEN -1, gPlayerNames[tempId]);
		} else {
			get_user_name(tempId, name, MAX_NAME_LEN -1);
		}
		if(equali(argGracz, name)){
			player = tempId;
		}
	}
	
	banName(id, argGracz, player, player);
	return PLUGIN_HANDLED;
}

public banPlayerById(id, player, doExecuteForward){
	new name[MAX_NAME_LEN];
	if( get_pcvar_num(gCvarRememberName)){
		copy(name, MAX_NAME_LEN -1, gPlayerNames[player]);
	} else {
		get_user_name(player, name, MAX_NAME_LEN -1);
	}	
	banName(id, name, player, doExecuteForward);
}

public banName(id, const name[], player, doExecuteForward) {
	new ban = 1;

	if(0<player<gMaxPlayers){
		gPlayerBanned[player] = 1
		if(get_pcvar_num(gCvarSkipSteam)){
			new steam[MAX_NAME_LEN];
			get_user_authid(player, steam, MAX_NAME_LEN -1);
			if(isValidSteam(steam))
			 ban = 0;
		}
		
	}
	if(ban){
		new nName[MAX_NAME_LEN];
		copy(nName, MAX_NAME_LEN -1, name);
		strtoupper(nName);
		nvault_set(gNvaultHandle, nName, name);
		if(id){
			client_print(id, print_console,gInfoBan , name);
			client_print(id, print_chat, gInfoBan, name);
		}
		if(get_pcvar_num(gCvarLog)){
			new admin[MAX_NAME_LEN];
			new steam[MAX_NAME_LEN];
			if(id){
				get_user_authid(id, steam, MAX_NAME_LEN-1);
				get_user_name(id, admin, MAX_NAME_LEN-1);
			} else{
				copy(admin, MAX_NAME_LEN-1, "AMXBANS");
			}
			log_to_file(gamx_nickBAN_LOG, gInfoBanned, admin, steam, name)
		}
		if(doExecuteForward && (0<player<gMaxPlayers) && (0<id<gMaxPlayers)){		
			ExecuteForward(gForwardHandle, resut, id, player);
		}
	} else {
		client_print(id, print_console,gPlayerWithSteam , name);
		client_print(id, print_chat, gPlayerWithSteam, name);
	}
}


public nickUnbanMenu(id, level, cid){
	if(!get_pcvar_num(gCvarActive))
		return PLUGIN_HANDLED;
	if(!cmd_access(id,level,cid,1)) 
		return PLUGIN_HANDLED;
	new menu = menu_create("\rZabijaka Nick UnBan Menu:", "unban_menu_handler");
	new players[32];
	new num;
	get_players(players, num);
	new sName[MAX_NAME_LEN *2 + 6];
	new tempid;
	new sTempid[3];
	new iNum = 0;
	new skipSteam = get_pcvar_num(gCvarSkipSteam);
	new name[MAX_NAME_LEN];
	new lockName =get_pcvar_num(gCvarLockName);
	new remName = get_pcvar_num(gCvarRememberName);
	for(new i=0;i< num;i ++){
		tempid = players[i];
		if(!gPlayerBanned[tempid])
			continue;
			
		if(skipSteam){
			get_user_authid(tempid, sName, charsmax(sName));
			if(isValidSteam(sName))
			    continue;
		}
		sName[0] = 0;
		if( remName ){
			copy(sName, MAX_NAME_LEN -1, gPlayerNames[tempid]);
		} else {
			get_user_name(tempid, sName, MAX_NAME_LEN -1);
		}
		
		num_to_str(tempid, sTempid, 2);
		
		if(!lockName){
			copy(name, MAX_NAME_LEN -1, gPlayerNames[tempid]);
			if(!equali(sName, name))
			format(sName, charsmax(sName), "%s [%s]", sName, name);
		}
		menu_additem(menu, sName, sTempid, 0);
		iNum++;
	}
	if(iNum)
		menu_display(id, menu, 0);
	else{
		client_print(id, print_chat, gNoPlayers);
		menu_destroy(menu);
	}
	return PLUGIN_HANDLED;
}

public unban_menu_handler(id, menu, item)
{
	if( item == MENU_EXIT )
	{
		menu_destroy(menu);
		return PLUGIN_HANDLED;
	}

	new data[6], szName[64];
	new acc, callback;
	menu_item_getinfo(menu, item, acc, data, charsmax(data), szName, charsmax(szName), callback);
	new tempid = str_to_num(data);	
	unbanPlayerById(id, tempid);	
	menu_destroy(menu);
	return PLUGIN_HANDLED;
}
public unbanPlayerById(id, player){
	new name[MAX_NAME_LEN];
	if( get_pcvar_num(gCvarRememberName)){
		copy(name, MAX_NAME_LEN -1, gPlayerNames[player]);
	} else {
		get_user_name(player, name, MAX_NAME_LEN -1);
	}
	unbanName(id, name, player);
}
public nickUnban(id, level, cid){
	if(!get_pcvar_num(gCvarActive))
		return PLUGIN_HANDLED;
	if(!cmd_access(id,level,cid,2)) 
		return PLUGIN_HANDLED;
	new argGracz[MAX_NAME_LEN];
	
	read_argv(1, argGracz, MAX_NAME_LEN -1);
	
	new player = cmd_target(id, argGracz, CMDTARGET_ALLOW_SELF);
	if(player && player < MAX_PLAYERS) {
		unbanPlayerById(id,player);
	}
	return PLUGIN_HANDLED;
}
public delNickBan(id, level, cid){
	if(!get_pcvar_num(gCvarActive))
		return PLUGIN_HANDLED;
	if(!cmd_access(id,level,cid,2)) 
		return PLUGIN_HANDLED;
	new argGracz[MAX_NAME_LEN];
	
	read_argv(1, argGracz, MAX_NAME_LEN - 1);
	
	new player = -1;
	new players[32];
	new num;
	get_players(players, num);
	new tempId;
	new name[MAX_NAME_LEN];
	new remName = get_pcvar_num(gCvarRememberName);
	for(new i=0;i<num;i++){
		tempId = players[i];
		if(remName){
			copy(name, MAX_NAME_LEN -1, gPlayerNames[tempId]);
		} else {
			get_user_name(tempId, name, MAX_NAME_LEN -1);
		}
		if(equali(argGracz, name)){
			player = tempId;
		}
	}
	
	unbanName(id, argGracz, player);
	return PLUGIN_HANDLED;
}

public unbanName(id, const name[], player) {
	new ban = 0;
	new nName[MAX_NAME_LEN];
	copy(nName, MAX_NAME_LEN -1, name);
	strtoupper(nName);
	new timeStamp;		
	new vData[MAX_NAME_LEN];
	
	if(nvault_lookup(gNvaultHandle, nName, vData, charsmax(vData),timeStamp))
		ban = 1;
	if(ban){
		nvault_remove(gNvaultHandle, nName);
		if(0<player<MAX_PLAYERS)
			gPlayerBanned[player] = 0;
			
		if(id){
			client_print(id, print_console,gInfoUnban , name);
			client_print(id, print_chat, gInfoUnban, name);
		}
		if(get_pcvar_num(gCvarLog)){
			new admin[MAX_NAME_LEN];
			new steam[MAX_NAME_LEN];
			if(id){
				get_user_authid(id, steam, MAX_NAME_LEN-1);
				get_user_name(id, admin, MAX_NAME_LEN-1);
			} else{
				copy(admin, MAX_NAME_LEN-1, "AMXBANS");
			}
			log_to_file(gamx_nickBAN_LOG, gInfoUnbanned, admin, steam, name)
		}		
	} else {
		client_print(id, print_console,gNickNotBanned , name);
		client_print(id, print_chat, gNickNotBanned, name);
	}
}





public client_connect(id){
	if(!is_user_connected(id)){
		set_task(2.0, "client_connect", id);
		return PLUGIN_CONTINUE;
	}
	
	if(get_pcvar_num(gCvarSkipSteam)){
		new steam[MAX_NAME_LEN];
		get_user_authid(id, steam, MAX_NAME_LEN -1);
		if(isValidSteam(steam))
			return PLUGIN_CONTINUE;
		if(contain(steam, "PENDING")){
			set_task(2.0, "checkBanned", id);
			return PLUGIN_CONTINUE;
		}
	}
	checkBanned(id);
	return PLUGIN_CONTINUE;
}

public checkBanned(id){
	gPlayerBanned[id] = 0;
	new name[MAX_NAME_LEN];
	get_user_name(id, name, MAX_NAME_LEN -1);	
	copy(gPlayerNames[id], MAX_NAME_LEN-1, name);
	
	strtoupper(name);
	new timeStamp;		
	new vData[MAX_NAME_LEN];
	
	if(nvault_lookup(gNvaultHandle, name, vData, charsmax(vData),timeStamp))
		gPlayerBanned[id] = 1;
}

public client_disconnect(id){
	gPlayerBanned[id] = 0;
	gPlayerNames[id][0] = 0;
}

public isValidSteam(const steamId[]){
	if(strfind(steamId, "STEAMID_0:") ==0 || strfind(steamId, "STEAMID_1:") ==0)
		return 1;
	return 0;
}
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1045\\ f0\\ fs16 \n\\ par }
*/
